<template>
  <l-layout class="l-form-design" :leftMove="false" :rightMove="false" :left="264" :right="344">
    <template #left>
      <l-panel
        :style="{
          'padding-right': 0,
          'padding-top': isNotTopPadding ? 0 : undefined,
          'padding-bottom': isNotBottomPadding ? 0 : undefined,
        }"
      >
        <div v-for="(myComponent, index) in myComponents" :key="index">
          <div class="l-form-design--myComponent-title">{{ $t(myComponent.title) }}</div>
          <draggable
            class="myComponent-item-draggable"
            :list="myComponent.list"
            :group="{ name: 'form', pull: 'clone', put: false }"
            ghost-class="ghost"
            :sort="false"
          >
            <div
              class="myComponent-item"
              @click="handleClick(item)"
              v-for="(item, index) in myComponent.list"
              :key="index"
            >
              <div class="myComponent-item-body">
                <i class="myComponent-item-icon" :class="item.icon"></i>
                <span>{{ $t(item.title || item.label) }}</span>
              </div>
            </div>
          </draggable>
        </div>
      </l-panel>
    </template>
    <l-panel
      :style="{
        'padding-left': 0,
        'padding-right': 0,
        'padding-top': isNotTopPadding ? 0 : undefined,
        'padding-bottom': isNotBottomPadding ? 0 : undefined,
      }"
    >
      <template #title>
        <el-button @click="handleClear" plain size="mini" type="danger" icon="el-icon-delete">清空</el-button>
        <el-button @click="handleViewer" plain size="mini" type="primary" icon="el-icon-video-play">预览</el-button>
      </template>

      <div class="l-rblock" style="padding: 11px">
        <div :class="['l-auto-window', { 'only-tabs': formInfo.tabList.length == 1 }]">
          <el-tabs v-model="formActiveName" type="card">
            <el-tab-pane
              v-for="(item, index) in formInfo.tabList"
              :key="index"
              :label="item.text"
              :name="'tab' + index"
            >
              <div
                class="l-rblock"
                :style="{ background: item.components.length == 0 ? `url(${imgUrl}) no-repeat 50%` : '' }"
              >
                <drag-form ref="dragForm" :myTabsIndex="index" :select.sync="dragFormSelect"></drag-form>
              </div>
            </el-tab-pane>
          </el-tabs>
        </div>
      </div>
    </l-panel>
    <template #right>
      <l-panel
        :style="{
          'padding-left': 0,
          'padding-top': isNotTopPadding ? 0 : undefined,
          'padding-bottom': isNotBottomPadding ? 0 : undefined,
        }"
      >
        <div class="l-auto-window">
          <el-tabs v-model="configActiveName" :stretch="true">
            <el-tab-pane :label="`${$t('组件属性')}${componentName}`" name="tab01">
              <component-config :data="dragFormSelect" ref="componentConfig"></component-config>
            </el-tab-pane>
            <el-tab-pane :label="$t('表单属性')" name="tab02">
              <form-config></form-config>
            </el-tab-pane>
          </el-tabs>
        </div>
      </l-panel>
    </template>

    <l-dialog
      v-if="formInfo.openType != '2'"
      :title="$t('表单预览')"
      :visible.sync="viewerVisible"
      :height="formInfo.dialogHeight || 600"
      :width="formInfo.dialogWidth || 800"
      @opened="handleFormOpened"
      @ok="handleCloseViewer"
    >
      <l-form-viewer ref="formViewer" :formInfo="viewerFormInfo"></l-form-viewer>
    </l-dialog>
    <l-drawer
      v-else
      :title="$t('表单预览')"
      :visible.sync="viewerVisible"
      :width="formInfo.drawerWidth || 600"
      @opened="handleFormOpened"
      @ok="handleCloseViewer"
    >
      <l-form-viewer ref="formViewer" :formInfo="viewerFormInfo"></l-form-viewer>
    </l-drawer>
  </l-layout>
</template>

<script>
import myComponents from "./components.js";
import FormConfig from "./config/formConfig";
import ComponentConfig from "./config/componentConfig";
import DragForm from "./dragForm";

export default {
  name: "l-form-design",
  components: {
    FormConfig,
    ComponentConfig,
    DragForm,
  },
  provide() {
    return {
      formDesign: this,
    };
  },
  props: {
    dbTables: {
      type: Array,
      default: () => [],
    },
    isNoScript: {
      type: Boolean,
      default: false,
    },
    isNotTopPadding: Boolean,
    isNotBottomPadding: Boolean,
  },
  data() {
    return {
      imgUrl: require("../../img/widget-empty.png"),

      myComponents,
      configActiveName: "tab01",

      formActiveName: "tab0",
      formInfo: {
        size: "mini",
        labelPosition: "right",
        labelWidth: 80,
        gutter: 0,
        openType: "1",
        dialogWidth: 800,
        dialogHeight: 600,
        drawerWidth: 600,
        historyType: "0",

        beforeSetData: "",
        afterValidateForm: "",
        changeDataEvent: "",
        afterSaveEvent: "",

        tabList: [{ components: [], text: "主表信息" }],
      },

      dragFormSelect: {},

      viewerVisible: false,
      viewerFormInfo: {},

      text1: "数据表",
      text2: "字段名",
      formType: "",
    };
  },
  computed: {
    componentName() {
      let res = "";
      if (this.dragFormSelect && this.dragFormSelect.type) {
        const len = this.myComponents.length;
        for (let i = 0; i < len; i++) {
          const list = this.myComponents[i].list;
          const item = list.find((t) => t.type == this.dragFormSelect.type);
          if (item) {
            res = `(${item.label})`;
            break;
          }
        }
      }
      return res;
    },
    nowComponentList() {
      const data = this.getData();
      const res = [];
      data.tabList.forEach((tab) => {
        tab.components.forEach((component) => {
          if (["gridtable"].includes(component.type)) {
            res.push(component);
            component.children.forEach((component2) => {
              component2.label = `${component.label}_${component2.label}`;
              component2.pprop = component.prop;
              res.push(component2);
            });
          } else {
            res.push(component);
          }
        });
      });

      return res;
    },
  },
  methods: {
    //表单类型
    setFormType(type) {
      //console.log(type); //常规表单0,视图表单1,接口模式2
      if (type == 2) {
        this.text1 = "接口";
        this.text2 = "字段名";
      } else {
        this.text1 = "数据表";
        this.text2 = "字段名";
      }
      this.formType = type;
      this.$refs.componentConfig.getFormType(type);
      return type;
    },

    handleClear() {
      this.dragFormSelect = {};
      this.formInfo.tabList[parseInt(this.formActiveName.replace("tab", ""))].components = [];
    },
    handleViewer() {
      this.viewerFormInfo = this.toSaveData();
      this.viewerVisible = true;
    },
    handleCloseViewer() {
      this.viewerVisible = false;
    },
    async handleFormOpened(showLoading, hideLoading) {
      showLoading("加载中...");
      await this.$refs.formViewer.init();
      hideLoading();
    },

    clear() {
      this.formInfo = {
        size: "mini",
        labelPosition: "right",
        labelWidth: 80,
        gutter: 0,
        openType: "1",
        dialogWidth: 600,
        dialogHeight: 400,
        drawerWidth: 600,
        tabList: [{ components: [], text: "主表信息" }],
      };
      this.configActiveName = "tab01";
      this.formActiveName = "tab0";
      this.dragFormSelect = {};
      this.viewerVisible = false;
      this.viewerFormInfo = {};
    },

    validate() {
      let tabName = "";
      let fieldMap = {};
      let tableMap = {};

      let flag = true;

      const data = this.getData();

      data.tabList.forEach((tab) => {
        if (data.tabList.length > 1) {
          tabName = `【${tab.text}】`;
        }
        tab.components.forEach((component) => {
          // 1.每一个组件必须要绑定数据表
          // 2.每一个组件必须要绑定数据表字段
          // 3.数据表不能重复，且子表不能是绑定主表
          if (!["viewtable", "card", "btn", "divider"].includes(component.type)) {
            if (["gridtable"].includes(component.type)) {
              if (tableMap[component.table]) {
                this.$message({
                  type: "error",
                  message: `${tabName}【${component.table}】子表单绑定表重复！`,
                });
                flag = false;
                return false;
              }
              tableMap[component.table] = 1;
            } else if (!component.subfield) {
              if (tableMap[component.table] == 1) {
                this.$message({
                  type: "error",
                  message: `${tabName}【${component.table}】子表单绑定表重复！`,
                });
                flag = false;
                return false;
              }
              tableMap[component.table] = 2;
            }

            if (!component.subfield) {
              if (this.$validatenull(component.table)) {
                this.$message({
                  type: "error",
                  message: `请${tabName}【${component.label}】绑定${this.text1}！`,
                });
                flag = false;
                return false;
              }
            }
            if (!["gridtable"].includes(component.type)) {
              if (this.$validatenull(component.field)) {
                this.$message({
                  type: "error",
                  message: `请${tabName}【${component.label}】绑定${this.text2}！`,
                });
                flag = false;
                return false;
              }

              if (fieldMap[`${component.table}-${component.field}`]) {
                this.$message({
                  type: "error",
                  message: `${tabName}【${component.label}】绑定${this.text2}重复！`,
                });
                flag = false;
                return false;
              }

              fieldMap[`${component.table}-${component.field}`] = true;
            }

            if (["gridtable"].includes(component.type)) {
              let gfield = {};
              component.children.forEach((item) => {
                if (this.$validatenull(item.field)) {
                  this.$message({
                    type: "error",
                    message: `请${tabName}子表中【${item.label}】绑定${this.text2}！`,
                  });
                  flag = false;
                  return false;
                }
                if (gfield[item.field]) {
                  this.$message({
                    type: "error",
                    message: `${tabName}子表中【${component.label}】绑定${this.text2}重复！`,
                  });
                  flag = false;
                  return false;
                }
                gfield[item.field] = true;
              });
            }

            if (["2", "3", "4"].includes(component.dataType)) {
              if (!component.dataCode) {
                let message = component.dataType == "2" ? "数据字典" : component.dataType == "3" ? "数据源" : "接口";

                this.$message({
                  type: "error",
                  message: `请${tabName}【${component.label}】选择${message}！`,
                });
                flag = false;
              }
            }

            if (["encode"].includes(component.type) && this.$validatenull(component.code)) {
              this.$message({
                type: "error",
                message: `请${tabName}【${component.label}】选择单据编码！`,
              });
              flag = false;
            }

            if (["layerselect"].includes(component.type) && component.columns.length <= 0) {
              this.$message({
                type: "error",
                message: `请${tabName}【${component.label}】选择设置列！`,
              });
              flag = false;
            }

            if (!flag) {
              return false;
            }
          }
        });

        if (!flag) {
          return false;
        }
      });

      return flag;
    },

    getData() {
      const data = this.toSaveData();
      return data;
    },
    setData(data) {
      this.formInfo = this.toShowData(data);
    },
    handleClick(item) {
      const index = parseInt(this.formActiveName.replace("tab", ""));
      this.$refs.dragForm[index].handleFormClickAdd(item);
    },

    updateTable() {
      this.formInfo.tabList.forEach((tab) => {
        tab.components.forEach((component) => {
          if (!this.$validatenull(component.table)) {
            const table = this.dbTables.find((t) => t.name == component.table);
            if (this.$validatenull(table)) {
              component.table = "";
              if (["gridtable"].includes(component.type)) {
                component.children.forEach((col) => {
                  col.field = "";
                  col.csType = "";
                });
              } else {
                component.field = "";
                component.csType = "";
              }
            } else if (["gridtable"].includes(component.type)) {
              component.children.forEach((col) => {
                const column = table.columns.find((t) => t.name == col.field);
                if (this.$validatenull(column)) {
                  col.field = "";
                  col.csType = "";
                } else {
                  col.csType = column.csType;
                  if (["switch"].includes(col.type)) {
                    col.activeValue = 1;
                    col.inactiveValue = 0;
                    col.valueType = "number";
                    // switch (col.csType) {
                    //   case "int":
                    //     col.activeValue = "1";
                    //     col.inactiveValue = "0";
                    //     col.valueType = "number";
                    //     break;
                    //   case "bool":
                    //     col.activeValue = "true";
                    //     col.inactiveValue = "false";
                    //     col.valueType = "boolean";
                    //     break;
                    //   default:
                    //     col.valueType = "string";
                    //     break;
                    // }
                  }
                }
              });
            } else {
              const column = table.columns.find((t) => t.name == component.field);
              if (this.$validatenull(column)) {
                component.field = "";
                component.csType = "";
              } else {
                component.csType = column.csType;
              }
            }
          }

          if (["switch"].includes(component.type) && !this.$validatenull(component.csType)) {
            component.activeValue = 1;
            component.inactiveValue = 0;
            component.valueType = "number";
            // switch (component.csType) {
            //   case "int":
            //     component.activeValue = "1";
            //     component.inactiveValue = "0";
            //     component.valueType = "number";
            //     break;
            //   case "bool":
            //     component.activeValue = "true";
            //     component.inactiveValue = "false";
            //     component.valueType = "boolean";
            //     break;
            //   default:
            //     component.valueType = "string";
            //     break;
            // }
          }
        });
      });
    },

    // 调整数据结构
    toSaveData() {
      // 转化成保存数据；为了兼容早期的版本只能保持和之前的数据格式一致
      const data = this.$deepClone(this.formInfo);
      data.tabList &&
        data.tabList.forEach((tab) => {
          const componentList = [];
          tab.components.forEach((component) => {
            if (["card"].includes(component.type)) {
              this.addChildren(component.children, componentList, component.prop, "card");
              delete component.children;
              componentList.push(component);
            } else {
              if (
                [
                  "guid",
                  "createuser",
                  "modifyuser",
                  "createtime",
                  "modifytime",
                  "encode",
                  "company",
                  "department",
                  "userSelect",
                  "departmentSelect",
                  "companySelect",
                ].includes(component.type)
              ) {
                component.default = "";
              } else if (component.type == "gridtable") {
                component.children.forEach((component2) => {
                  if (
                    [
                      "guid",
                      "createuser",
                      "modifyuser",
                      "createtime",
                      "modifytime",
                      "encode",
                      "company",
                      "department",
                      "userSelect",
                      "departmentSelect",
                      "companySelect",
                    ].includes(component.type)
                  ) {
                    component2.default = "";
                  }
                });
              }
              componentList.push(component);
            }
          });
          tab.components = componentList;
        });

      return data;
    },
    addChildren(list, componentList, pid, ptype) {
      list.forEach((component) => {
        component.pid = pid;
        component.ptype = ptype;
        if (["card"].includes(component.type)) {
          this.addChildren(component.children, componentList, component.prop, "card");
          delete component.children;
          componentList.push(component);
        } else {
          if (["rate", "slider"].includes(component.type)) {
            component.default = 0;
          } else if (
            [
              "guid",
              "createuser",
              "modifyuser",
              "createtime",
              "modifytime",
              "encode",
              "company",
              "department",
              "userSelect",
              "departmentSelect",
              "companySelect",
            ].includes(component.type)
          ) {
            component.default = "";
          } else if (component.type == "gridtable") {
            component.children.forEach((component2) => {
              if (
                [
                  "guid",
                  "createuser",
                  "modifyuser",
                  "createtime",
                  "modifytime",
                  "encode",
                  "company",
                  "department",
                  "userSelect",
                  "departmentSelect",
                  "companySelect",
                ].includes(component.type)
              ) {
                component2.default = "";
              }
            });
          }
          componentList.push(component);
        }
      });
    },

    toShowData(data) {
      // 转化成显示数据
      const myData = this.$deepClone(data);
      if (myData.historyType == undefined) {
        myData.historyType = "0";
      }

      const pMap = {};
      myData.tabList &&
        myData.tabList.forEach((tab) => {
          const componentList = [];
          tab.components.forEach((component) => {
            if (["card"].includes(component.type)) {
              if (!pMap[component.prop]) {
                pMap[component.prop] = [];
              }
              component.children = pMap[component.prop];
            }

            if (component.ptype == "card") {
              if (!pMap[component.pid]) {
                pMap[component.pid] = [];
              }
              pMap[component.pid].push(component);
              delete component.pid;
              delete component.ptype;
            } else {
              componentList.push(component);
            }
          });
          tab.components = componentList;
        });
      return myData;
    },
  },
};
</script>

<style lang="less">
@import "./index.less";
</style>
